<?php
	/*
		Simpler 3D-Plotter

		Aktion: PHP Scripte für die armen dieser Welt
		Der Erlös geht für mein Pausenbrot drauf

		Copyright (c) 2006 by Phillip 'Firebird' Berndt
	*/

	
	if(!isset($_POST['points']))
	{
		$_POST['points'] = base64_decode('
			UHVua3RlIHdlcmRlbiB3aWUgaW0gTWF0aGVtYXRpa3VudGVycmljaHQgbWFya2llcnQ6CgpQKDAs
			MCwwKQpRKDAsMCw0KQpSKDAsNCw0KQpSJygwLDQsMCkKUyg0LDQsNCkKVCg0LDAsNCkKVSg0LDQs
			MCkKVScoNCwwLDApCgpvZGVyCgpaKDB8MHwwKQoKU28gbGFzc2VuIHNpY2ggVmVyYmluZHVuZ2Vu
			IHp3aXNjaGVuIFB1bmt0ZW4gbWFsZW46CgpQPT5VJwpVJy0+VQpVLT5SJwpSJz0+UApQPT5RClUn
			LT5UClUtPlMKUictPlIKUS0+UgpRLT5UClQtPlMKUy0+UgoKVmVyYmluZHVuZ2VuIG1pdCBlaW5l
			bSAtIHdlcmRlbiBzdGFyaywgc29sY2hlIG1pdCBlaW5lbSA9IGxlaWNodCBnZW1hbHQuCgpTbyBs
			YXNzZW4gc2ljaCBkaWUgRWluc3RlbGx1bmdlbiBtb2RpZml6aWVyZW46Cgp1bml0TGVuZ3RoPTUw
			CnhBbmdsZT00NQp4QXhpc0Rldmlzb3I9Mg==
		');
	}
	
	if(isset($_GET['points']))
	{
		// Extract commands
		preg_match_all('/^([a-z0-9\']*)\s*\(\s*([0-9]+)\s*(?:,|\|)\s*([0-9]+)\s*(?:,|\|)\s*([0-9]+)\s*\)/im', $_GET['points'], $points);
		preg_match_all('/^([a-z0-9\']*)\s*(-|=)>([a-z0-9\']*)/im', $_GET['points'], $connections);
		preg_match_all('/^(unitLength|xAngle|xAxisDevisor)=([0-9.]+)/mi', $_GET['points'], $settings, PREG_SET_ORDER);
		
		// Settings
		$unitLength		= 50;
		$xAngle 		= 45/180*pi();
		$unitLengthX	= $unitLength / 2;
		foreach($settings as $setting)
		{
			switch(strtolower($setting[1]))
			{
				case 'unitlength':
					$unitLength = intval($setting[2]);
					$unitLengthX = $unitLength / 2;
					break;
				case 'xangle':
					$$xAngle = intval($setting[2]) / 180 * pi();
					break;
				case 'xaxisdevisor':
					$unitLengthX = $unitLength / intval($setting[2]);
					break;
			}
		}
		
		// Create environment
		$xMin 			= min(0, min($points[2])); $xMax = max(0, max($points[2])); $xMax = abs(max($xMax, $xMin)); $xMin = -$xMax;
		$yMin 			= min(0, min($points[3])); $yMax = max(0, max($points[3])); $yMax = abs(max($yMax, $yMin)); $yMin = -$yMax;
		$zMin 			= min(0, min($points[4])); $zMax = max(0, max($points[4])); $zMax = abs(max($zMax, $zMin)); $zMin = -$zMax;
		$imageWidth  	= abs($yMin * $unitLength) + abs($yMax * $unitLength) + 10;
		$imageHeight 	= abs($zMin * $unitLength) + abs($zMax * $unitLength) + 10;
		$imageCenterX 	= $imageWidth  / 2;
		$imageCenterY 	= $imageHeight / 2;
		$cs 			= imagecreatetruecolor($imageWidth + 9, $imageHeight + 9);
		$white 			= imagecolorallocate($cs, 255, 255, 255);
		$gray			= imagecolorallocate($cs, 200, 200, 200);
		$black 			= imagecolorallocate($cs, 0, 0, 0);
		$red 			= imagecolorallocate($cs, 255, 0, 0);
		$blue			= imagecolorallocate($cs, 0, 0, 255);
		$lightBlue		= imagecolorallocate($cs, 200, 200, 255);
		
		// Draw coordinate system
		imagefill($cs, 0, 0, $white);
		imageline($cs, $imageCenterX, 5, $imageCenterX, $imageHeight - 5, $black);
		imageline($cs, $imageCenterX - 3, 8, $imageCenterX, 5, $black);
		imageline($cs, $imageCenterX + 3, 8, $imageCenterX, 5, $black);
		imagestring($cs, 0, $imageCenterX - 7, 2, 'Z', $black);
		for($z=$zMin + 1; $z<=$zMax; $z++)
		{
			imageline($cs, $imageCenterX - 3, $imageCenterY + $z * $unitLength, $imageCenterX, $imageCenterY + $z * $unitLength, $black);
			imagestring($cs, 0, $imageCenterX - 12, $imageCenterY + $z * $unitLength - 10, -$z, $gray); 
		}
		imageline($cs, 5, $imageCenterY, $imageWidth - 5, $imageCenterY, $black);
		imageline($cs, $imageWidth - 8, $imageCenterY + 3, $imageWidth - 5, $imageCenterY, $black);
		imageline($cs, $imageWidth - 8, $imageCenterY - 3, $imageWidth - 5, $imageCenterY, $black);
		imagestring($cs, 0, $imageWidth - 8, $imageCenterY - 10, 'Y', $black);
		for($y=$yMin; $y<$yMax; $y++)
		{
			imageline($cs, $unitLength * $y + $imageCenterX, $imageCenterY + 3, $unitLength * $y + $imageCenterX, $imageCenterY, $black);
			imagestring($cs, 0, $unitLength * $y + $imageCenterX + 3, $imageCenterY + 4, $y, $gray); 
		}
		imageline($cs,
			$imageCenterX + ($xMax + 2) * $unitLengthX * cos($xAngle),
			$imageCenterY - ($xMax + 2) * $unitLengthX * sin($xAngle),
			$imageXAxisEndX = ($imageCenterX - ($xMax + 2) * $unitLengthX * cos($xAngle)),
			$imageXAxisEndY = ($imageCenterY + ($xMax + 2) * $unitLengthX * sin($xAngle)),
			$black);
		imageline($cs, $imageXAxisEndX + 5 * cos($xAngle - 0.5), $imageXAxisEndY - 5 * sin($xAngle - 0.5), $imageXAxisEndX, $imageXAxisEndY, $black);
		imageline($cs, $imageXAxisEndX + 5 * cos($xAngle + 0.5), $imageXAxisEndY - 5 * sin($xAngle + 0.5), $imageXAxisEndX, $imageXAxisEndY, $black);
		imagestring($cs, 0, $imageXAxisEndX - 5, $imageXAxisEndY - 5, 'X', $black);
		for($x=$xMin; $x<=$xMax; $x++)
		{
			$imagePointX = $imageCenterX - $x * $unitLengthX * cos($xAngle);
			$imagePointY = $imageCenterY + $x * $unitLengthX * sin($xAngle);	
			imageline($cs, $imagePointX, $imagePointY, $imagePointX - 3 * cos($xAngle + pi()/2), $imagePointY - 3 * cos($xAngle + pi()/2), $black);
			imagestring($cs, 0, $imagePointX + 3, $imagePointY + 3, $x, $gray);
		}
		
		// Draw points
		$pointPositions = Array();
		for($n=0; $n<count($points[0]); $n++)
		{
			$coordinateX = $imageCenterX - $points[2][$n] * $unitLengthX * cos($xAngle);
			$coordinateY = $imageCenterY + $points[2][$n] * $unitLengthX * sin($xAngle);
			$coordinateX += $points[3][$n] * $unitLength;
			$coordinateY -= $points[4][$n] * $unitLength;
			imagefilledellipse($cs, $coordinateX, $coordinateY, 2, 2, $red);
			imagestring($cs, 0, $coordinateX + 3, $coordinateY + 3, $points[1][$n], $red);
			$pointPositions[strtolower($points[1][$n])] = array($coordinateX, $coordinateY);
		}
		
		// Draw connections
		for($n=0; $n<count($connections[0]); $n++)
			imageline($cs, $pointPositions[strtolower($connections[1][$n])][0], $pointPositions[strtolower($connections[1][$n])][1],
				$pointPositions[strtolower($connections[3][$n])][0], $pointPositions[strtolower($connections[3][$n])][1],
				$connections[2][$n] == '-' ? $blue : $lightBlue);
		
		header('Content-type: image/png');
		imagepng($cs);
		die();
	}
	
?>
<h1>Simpler 3D Plot</h1>
<form method="post">
<textarea rows="20" cols="80" name="points"><?=htmlspecialchars($_POST['points'])?></textarea><br/>
<input type="submit">
</form>
<hr/>
<img src="<?=$_SERVER['PHP_SELF']?>?points=<?=urlencode($_POST['points'])?>" alt="3D Plot"/>
